package log

import (
	"fmt"
	"io"
	"os"
	"sync"
	"time"
)

var logWriter io.Writer
var once sync.Once

type FormatterParam struct {
	LogMsg   string
	LogLevel Level
}

type LogFormatter func(param FormatterParam) string

var Formatter LogFormatter

var defaultFormatter LogFormatter = func(param FormatterParam) string {
	return fmt.Sprintf("[%s] %v - %s",
		param.LogLevel.GetName(),
		time.Now().Format("2006/01/02 - 15:04:05"),
		param.LogMsg)
}

func Init(writer io.Writer) {
	logWriter = writer
}

func getLogWriter() io.Writer {
	once.Do(func() {
		if logWriter == nil {
			logWriter = os.Stdout
		}
	})
	return logWriter
}

func log(logLevel Level, msg string) {
	formatter := Formatter
	if formatter == nil {
		formatter = defaultFormatter
	}
	fmt.Fprintln(getLogWriter(), formatter(FormatterParam{
		LogMsg:   msg,
		LogLevel: logLevel,
	}))
}

func Info(format string, args ...interface{}) {
	log(INFO, fmt.Sprintf(format, args...))
}

func Error(format string, args ...interface{}) {
	log(ERROR, fmt.Sprintf(format, args...))
}

func Debug(format string, args ...interface{}) {
	log(DEBUG, fmt.Sprintf(format, args...))
}

func Warn(format string, args ...interface{}) {
	log(WARN, fmt.Sprintf(format, args...))
}
